package org.hxzon.tapestry5.components;

import java.util.Date;

import org.apache.tapestry5.Asset;
import org.apache.tapestry5.Binding;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.Environmental;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.base.AbstractField;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.ComponentDefaultProvider;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;
import org.hxzon.util.DateFormatUtil;

//www.eyecon.ro
@Import(stylesheet = { "datepicker/css/datepicker.css" }, library = { "datepicker/js/datepicker.js", "datefieldEx.js" })
public class DateFieldEx extends AbstractField {
    @Parameter(required = true, principal = true)
    @Property
    private Date value;

    //@Parameter(value = "Y-m-d", defaultPrefix = BindingConstants.LITERAL)
    private final String jsFormat = "Y-m-d";
    private final String javaFormat = "yyyy-MM-dd";

    ////Whatever if the date picker is appended to the element or triggered by an event. Default false
    @Parameter(value = "false")
    private boolean flat;

    ////The day week start. Default 1 (monday)
    @Parameter(value = "1")
    private int start;

    //Date selection mode.['single'|'multiple'|'range']
    @Parameter(value = "single", defaultPrefix = BindingConstants.LITERAL)
    private String mode;

    //Start view mode. Default 'days'.['days'|'months'|'years']
    //@Parameter(value = "days", defaultPrefix = BindingConstants.LITERAL)
    private final String view = "days";

    //Number of calendars to render inside the date picker. Default 1
    @Parameter(value = "1")
    private int calendars;

    //Date picker's position relative to the trigger element (non flat mode only). Default 'bottom'.
    //['top'|'left'|'right'|'bottom']
    @Parameter(value = "bottom", defaultPrefix = BindingConstants.LITERAL)
    private String position;
    
    //locale
    //hash
    //Location: provide a hash with keys 'days', 'daysShort', 'daysMin', 'months', 'monthsShort', 'week'. Default english

    @Parameter(defaultPrefix = BindingConstants.ASSET, value = "datefield.gif")
    private Asset icon;

    @Inject
    private Request request;

    @Environmental
    private JavaScriptSupport support;

    @Inject
    private ComponentResources resources;

    @Inject
    private ComponentDefaultProvider defaultProvider;

    final Binding defaultValidate() {
        return defaultProvider.defaultValidatorBinding("value", resources);
    }

    void beginRender(MarkupWriter writer) {
        String clientId = getClientId();
        String triggerId = clientId + "-trigger";
        String calendarId = clientId + "-calendar";

        writer.element("input", "type", "text", "name", getControlName(), "id", clientId, "readonly", "readonly", "value", DateFormatUtil.format(value, javaFormat));
        writeDisabled(writer);
        resources.renderInformalParameters(writer);
        decorateInsideField();
        writer.end();//input

        // Now the trigger icon.
        writer.element("img", "id", triggerId, "class", "t-calendar-trigger", "src", icon.toClientURL(), "alt", "[Show]");
        writer.end(); // img

        writer.element("p", "id", calendarId);
        writer.end();//p

        JSONObject spec = new JSONObject();

        spec.put("field", clientId);
        spec.put("date", DateFormatUtil.format(value, javaFormat));
        spec.put("format", jsFormat);
        spec.put("flat", flat);
        spec.put("start", start);
        spec.put("mode", mode);
        spec.put("view", view);
        spec.put("calendars", calendars);
        spec.put("position", position);
        support.addInitializerCall("dateFieldEx", spec);
    }

    private void writeDisabled(MarkupWriter writer) {
        if (isDisabled()) {
            writer.attributes("disabled", "disabled");
        }
    }

    @Override
    protected void processSubmission(String controlName) {
        this.value = DateFormatUtil.parse(request.getParameter(controlName), javaFormat);
    }
}
